package com.archtecture.view.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;

import com.archtecture.control.enums.Arquivo;
import com.archtecture.control.enums.Mensagem;
import com.archtecture.control.exceptions.NegocioException;
import com.archtecture.control.facedes.GenericPersistenceFacadeRemote;
import com.archtecture.control.models.ModelAb;
import com.archtecture.view.utils.UtilWeb;

public abstract class PadraoCrudMB<Model extends ModelAb> implements Serializable {

	/**
	 * 
	 */
	private static final long				serialVersionUID	= -305963397064845867L;

	private Model							model;

	private List<Model>						modelList;

	private boolean							editando;

	private String							tituloPagina;

	@EJB
	private GenericPersistenceFacadeRemote	persistenceFacade;

	public PadraoCrudMB() {
		configurarParametrosPreCarregamentoPagina();
	}

	public void cancelar() {
		setEditando(false);
		setModel(null);
	}

	public void configurarParametrosPreCarregamentoPagina() {

	}

	public void deletar() {

		try {
			doDeletar();
			persistenceFacade.excluir(getModel());
			modelList.remove(model);
			UtilWeb.enviarMensagem(FacesMessage.SEVERITY_INFO, Mensagem.MSG_SUCESSO_DELETAR);

		} catch (NegocioException e) {
			UtilWeb.enviarMensagem(FacesMessage.SEVERITY_ERROR, e.getMensagemErro());
		}

		setModel(null);
	}

	public void doDeletar() throws NegocioException {}

	public void doEditar() throws NegocioException {}

	public void doSalvar() throws NegocioException {}

	public void editar() {

		try {
			doEditar();
			setEditando(true);
			Model model = sincronizarModelDaLista(getModel().getCodigo());
			setModel(model);
		} catch (NegocioException e) {
			UtilWeb.enviarMensagem(FacesMessage.SEVERITY_ERROR, e.getMensagemErro());
		}
	}

	public abstract Model getInstance();

	/**
	 * @return the model
	 */
	public Model getModel() {
		if (model == null) {
			model = getInstance();
		}
		return model;
	}

	/**
	 * @return the modelList
	 */
	public List<Model> getModelList() {
		if (modelList == null) {
			modelList = new ArrayList<Model>();
		}
		return modelList;
	}

	/**
	 * @return the persistenceFacade
	 */
	protected GenericPersistenceFacadeRemote getPersistenceFacade() {
		return persistenceFacade;
	}

	/**
	 * @return the tituloPagina
	 */
	public String getTituloPagina() {

		String nomeRecurso = editando ? "sistema_tituloPaginaCadastro" : "sistema_tituloPaginaPesquisa";

		tituloPagina = UtilWeb.obterTextoArquivo(Arquivo.LABELS, nomeRecurso) + " "
				+ UtilWeb.obterTextoArquivo(Arquivo.LABELS, getModel().getClass().getSimpleName());

		return tituloPagina;
	}

	/**
	 * @return the editando
	 */
	public boolean isEditando() {
		return editando;
	}

	public void novoItem() {
		setEditando(true);
		setModel(null);
	}

	public void pesquisar() {

		try {

			List<Model> lModelList = null;
			lModelList = persistenceFacade.pesquisarLista(getModel());
			if (lModelList.isEmpty()) {
				UtilWeb.enviarMensagem(FacesMessage.SEVERITY_WARN, Mensagem.ERRO_PESQUISA_VAZIA);
			}
			setModelList(lModelList);

		} catch (NegocioException e) {
			UtilWeb.enviarMensagem(FacesMessage.SEVERITY_ERROR, e.getMensagemErro());
		}

	}

	public void salvar() {

		try {

			doSalvar();

			if (getModel().getCodigo() == null || getModel().getCodigo().equals(0)) {
				setModel(persistenceFacade.inserir(getModel()));
				getModelList().add(model);
				UtilWeb.enviarMensagem(FacesMessage.SEVERITY_INFO, Mensagem.MSG_SUCESSO_SALVAR);
			}

			else {
				persistenceFacade.atualizar(getModel());
				UtilWeb.enviarMensagem(FacesMessage.SEVERITY_INFO, Mensagem.MSG_SUCESSO_EDITAR);
			}

			setModel(null);

		} catch (NegocioException e) {
			UtilWeb.enviarMensagem(FacesMessage.SEVERITY_ERROR, e.getMensagemErro());
		}
	}

	/**
	 * @param editando
	 *            the editando to set
	 */
	public void setEditando(boolean editando) {
		this.editando = editando;
	}

	/**
	 * @param model
	 *            the model to set
	 */
	public void setModel(Model model) {
		this.model = model;
	}

	/**
	 * @param modelList
	 *            the modelList to set
	 */
	public void setModelList(List<Model> modelList) {
		this.modelList = modelList;
	}

	/**
	 * @param tituloPagina
	 *            the tituloPagina to set
	 */
	public void setTituloPagina(String tituloPagina) {
		this.tituloPagina = tituloPagina;
	}

	private Model sincronizarModelDaLista(Integer codigo) {
		for (Model model : getModelList()) {
			if (model.getCodigo().equals(codigo)) {
				return model;
			}
		}
		return null;
	}

}
